#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import argparse
import ConfigParser
import os
import re
import sys
import tweepy
from daemon import DaemonContext
from daemon.pidlockfile import PIDLockFile
from textwrap import TextWrapper

from NetEbbms import NetEbbms

import psyco
psyco.full()

class StreamWatcherListener(tweepy.StreamListener): 
	status_wrapper = TextWrapper(width = 60, initial_indent = '    ', subsequent_indent = '    ')

	def __init__(self, netebbms, config):
		tweepy.StreamListener.__init__(self)

		self.netebbms = netebbms
		self.config = config
		self.hashtags = config.get('behavior', 'hashtags').replace(' ', '').split(',')


	def on_status(self, status):
		try:
			print self.status_wrapper.fill(status.text)
			print '\n %s  %s  via %s\n' % (status.author.screen_name, status.created_at, status.source)

			for hashtag in self.hashtags:
				if (re.search(('#' + hashtag).decode('utf-8'), status.text) != None or
					(len(self.hashtags) == 1 and self.hashtags[0] == '')):

					self.netebbms.setText(
						generator = 'twitter',
						memo = '[' + status.author.screen_name.encode('utf-8') + '  ' + status.author.name.encode('utf-8') + ']\n' +
							status.source.encode('utf-8') + '\n' + status.text.encode('utf-8'),
						mode = 'COUNT',
						enable = True,
						count = 1,
						end_time = 0.0,
						backcolor = self.config.get('style_common', 'backcolor'),
						textstyle = (
							{
								'text' : status.text.encode('utf-8'),
								'fontpath' : self.config.get('style_tweettext', 'fontpath'),
								'color' : self.config.get('style_tweettext', 'color'),
								'point' : self.config.getint('style_tweettext', 'point'),
								'scroll' : self.config.getint('style_tweettext', 'scroll'),
								'positionY' : self.config.getint('style_tweettext', 'positionY')
							},
							{
								'text' : status.author.screen_name.encode('utf-8'),
								'fontpath' : self.config.get('style_author', 'fontpath'),
								'color' : self.config.get('style_author', 'color'),
								'point' : self.config.getint('style_author', 'point'),
								'scroll' : self.config.getint('style_author', 'scroll'),
								'positionX' : self.config.getint('style_author', 'positionX'),
								'positionY' : self.config.getint('style_author', 'positionY')
							}
						)
					)
					break

		except KeyboardInterrupt:
			myNetEbbms.close()
			sys.exit(1)

		except Exception, ex:
			print ex

		except:
			# Catch any unicode errors while printing to console
			# and just ignore them to avoid breaking application.
			pass


	def on_error(self, status_code):
		print 'An error has occured! Status code = %s' % status_code
		return True  # keep stream alive

	
	def on_timeout(self):
		print 'Snoozing Zzzzzz'
		return True


def main():
	# スクリプトパスを取得 #
	scriptDirPath = os.path.abspath(os.path.dirname(__file__))


	# 設定ファイルディレクトリパスを取得 #
	configDirPath = os.path.join(os.path.split(os.path.split(scriptDirPath)[0])[0], 'config')


	# 設定ファイルパスを取得 #
	configFilePath = os.path.join(configDirPath, 'netebbms.conf')


	# モデル リスト ファイル パスを取得 #
	modelListFilePath = os.path.join(configDirPath, 'model.list')


	# インスタンス作成 #
	myNetEbbms = NetEbbms(configFilePath, modelListFilePath)


	# 設定ファイル読み込み #
	config = ConfigParser.SafeConfigParser()
	config.read(os.path.join(scriptDirPath, 'twitterclient.conf'))


	# OAuth認証 #
	auth = tweepy.OAuthHandler(config.get('account', 'consumerkey'), config.get('account', 'consumersecret'))
	auth.set_access_token(config.get('account', 'accesstokenkey'), config.get('account', 'accesstokensecret'))


	# REST API 設定 #
	api = tweepy.API(auth_handler = auth, secure = True)


	# Streaming API 設定 #
	stream = tweepy.Stream(auth, StreamWatcherListener(myNetEbbms, config),
		timeout = config.getint('behavior', 'timeout'), secure = False)


	# 表示するtweetを設定 #
	valid_authorclass = ('friends', 'followers')
	authorclass = [u for u in config.get('behavior', 'tweetselect').replace(' ','').split(',')]

	friendList = set(api.friends_ids())
	followerList = set(api.followers_ids())
	author = set()

	if 'friends' in authorclass:
		author |= friendList
	if 'followers' in authorclass:
		author |= followerList
	if len(author) == 0:
		author |= friendList
		author |= followerList

	# tweetを取得 #
	try:
		stream.filter(author)

	except Exception, ex:
		print >> sys.stderr, ex
		sys.exit(1)

	finally:
		myNetEbbms.close()


if __name__ == "__main__":
	# コマンドラインオプションをパース #
	parser = argparse.ArgumentParser()
	parser.add_argument(
		'-d', '--daemon',
		action = 'store_true',
		default = False,
		dest = 'runDaemon',
		help = 'run this script as daemon'
	)
	args = parser.parse_args()

	try:
		if args.runDaemon == True:
			# デーモンとして起動 #
			dc = DaemonContext(
				pidfile = PIDLockFile('/var/run/netebbms/twitterclient.pid'),
				stderr = open('/var/log/netebbms/twitterclient_error.log', 'w+')
			)
	
			with dc:
				main()

		else:
			# コマンドとして起動 #
			main()

	except KeyboardInterrupt:
		pass

	except Exception, ex:
		print >> sys.stderr, ex
		sys.exit(1)

